import { debounce, to } from '@/tools';
import { describe, expect, it } from 'vitest';

describe('to function', () => {
  it('当期约处理完成时，应返[null, data]', async () => {
    const promise = Promise.resolve('data');
    const [error, data] = await to(promise)
    expect(error).toBeNull()
    expect(data).toBe('data');
  })

  it('当期约处理完成时，应返 [error, undefined]', async () => {
    const promise = Promise.reject(new Error('error'));
    const [error, data] = await to(promise)
    expect(error).toBe('error');
    expect(data).toBeUndefined()
  });

  it(' 当期约处理完成时，应返[parsedError, undefined]', async () => {
    const promise = Promise.reject(new Error('error'));
    const errorExt = { code: 404 }
    const [error, data] = await to(promise, errorExt)
    expect(error).toEqual({ code: 404, msg: 'error' })
    expect(data).toBeUndefined()
  });
})

describe('debounce function', () => {
  it('应返回函数', () => {
    const debouncedFunc = debounce(() => {}, 100)
    expect(typeof debouncedFunc).toBe('function');
  })

  it('应延迟执行函数', async () => {
    let called = false
    const debouncedFunc = debounce(() => {
      called = true
    }, 100)
    debouncedFunc()
    await new Promise(resolve => setTimeout(resolve, 150))
    expect(called).toBe(true)
  });

  it('测试防抖作用', async () => {
    let callCount = 0
    const debouncedFunc = debounce(() => {
      callCount++
    }, 100)
    debouncedFunc()
    debouncedFunc()
    await new Promise(resolve => setTimeout(resolve, 50))
    expect(callCount).toBe(0)
  });

  it('测试立即执行', async () => {
    let called = false
    const debouncedFunc = debounce(
      () => {
        called = true
      },
      100,
      true,
    )
    debouncedFunc()
    await new Promise(resolve => setTimeout(resolve, 50))
    expect(called).toBe(true)
  });

  it('测试非立即执行', async () => {
    let called = false
    const debouncedFunc = debounce(
      () => {
        called = true
      },
      100,
      false,
    )
    debouncedFunc()
    await new Promise(resolve => setTimeout(resolve, 50))
    expect(called).toBe(false)
  });
})
